const doc = window.document.implementation.createHTMLDocument("");
const div = doc.createElement("div");

export function removeHTML(htmlString: string) {
  div.innerHTML = htmlString;
  let elements = div.querySelectorAll("*");
  while (elements.length) {
    div.innerHTML = div.innerText;
    elements = div.querySelectorAll("*");
  }
  return div.innerText;
}

/**
 * 格式化html
 * 替换 < > & 符号
 * @param htmlString
 */
export function escapeHTML(htmlString: { toString: () => string }) {
  try {
    return htmlString.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  } catch (e) {
    return "";
  }
}

/**
 * 把html转换为安全的html
 * @param htmlString
 */
export function safeHTML(htmlString: string) {
  div.innerHTML = htmlString;

  for (let elements = div.querySelectorAll("*"), i = elements.length - 1; i >= 0; i--) {
    const element = elements[i],
      tagName = element.localName;

    if (tagName == "script" || tagName == "noscript" || tagName == "noembed" || !(element.attributes instanceof NamedNodeMap)) {
      try {
        element.parentNode?.removeChild(element);
      } catch (e) {
        element.outerHTML = "";
      }
      continue;
    }

    if (!element.hasAttributes()) continue;

    for (let attributes = element.attributes, j = attributes.length - 1; j >= 0; j--) {
      const attribute = attributes[j],
        attributeName = attribute.localName,
        attributeValue = attribute.value
          .replace(
            // eslint-disable-next-line no-control-regex
            /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g,
            ""
          )
          .toLowerCase()
          .trim();

      // Remove insecure attribute starting "on*" (example: <img src='' onerror=alert(1)>)
      if (attributeName.indexOf("on") == 0) element.removeAttribute(attributeName);
      // Remove insecure src/href attribute with value starting "javascript:*" (example: href="javascript:alert(1)")
      else if ((attributeName == "src" || attributeName == "href") && attributeValue.indexOf("javascript:") == 0)
        element.removeAttribute(attributeName);
      // For non-specific tags remove insecure src/data attribute with value starting "data:*" (example: <embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">)
      else if (
        ["audio", "image", "img", "source", "video"].indexOf(tagName) == -1 &&
        (attributeName == "src" || attributeName == "data") &&
        attributeValue.indexOf("data:") == 0
      )
        element.removeAttribute(attributeName);
    }
  }

  return div.innerHTML;
}
